// Ch3_1.cpp : Initialization functions

// CH3_1.cpp
// by Charles Mc Auley
// "Programming AutoCAD 2000 with ObjectARX"
//
// This application defined a command 'RBCIRC', which
// stands for Result Buffer CIRCle. Here we create a
// a circle using result buffer technology and then using
// the same result buffer, we traverse the result buffer
// and extract the newly created entity information from a
// resutl buffer.
// This application represents the old style methods for
// creating AutoCAD entities and this method has been
// superceded by ObjectARX.
//
/////////////////////////////////////////////////////////

#include "StdAfx.h"
#include "StdArx.h"
#include "resource.h"

HINSTANCE _hdllInstance =NULL ;

// This command registers an ARX command.
void AddCommand(const char* cmdGroup, const char* cmdInt, const char* cmdLoc,
				const int cmdFlags, const AcRxFunctionPtr cmdProc, const int idLocal = -1);

// NOTE: DO NOT edit the following lines.
//{{AFX_ARX_MSG
void InitApplication();
void UnloadApplication();
//}}AFX_ARX_MSG

// NOTE: DO NOT edit the following lines.
//{{AFX_ARX_ADDIN_FUNCS
//}}AFX_ARX_ADDIN_FUNCS

/////////////////////////////////////////////////////////////////////////////
// DLL Entry Point
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
	if (dwReason == DLL_PROCESS_ATTACH)
	{
        _hdllInstance = hInstance;
	} else if (dwReason == DLL_PROCESS_DETACH) {
	}
	return TRUE;    // ok
}



/////////////////////////////////////////////////////////////////////////////
// ObjectARX EntryPoint
extern "C" AcRx::AppRetCode 
acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
	switch (msg) {
	case AcRx::kInitAppMsg:
		// Comment out the following line if your
		// application should be locked into memory
		acrxDynamicLinker->unlockApplication(pkt);
		acrxDynamicLinker->registerAppMDIAware(pkt);
		InitApplication();
		break;
	case AcRx::kUnloadAppMsg:
		UnloadApplication();
		break;
	}
	return AcRx::kRetOK;
}


// Init this application. Register your
// commands, reactors...
void InitApplication()
{
	// NOTE: DO NOT edit the following lines.
	//{{AFX_ARX_INIT
	AddCommand("CH3_APPS", "RBCIRC", "RBCIRC", ACRX_CMD_MODAL, rbcirc);
	//}}AFX_ARX_INIT

	// TODO: add your initialization functions
	acutPrintf("Enter \"RBCIRC\" at the command prompt to execute.\n");
}

// Unload this application. Unregister all objects
// registered in InitApplication.
void UnloadApplication()
{
	// NOTE: DO NOT edit the following lines.
	//{{AFX_ARX_EXIT
	acedRegCmds->removeGroup("CH3_APPS");
	//}}AFX_ARX_EXIT

	// TODO: clean up your application
	acutPrintf("%s%s", "Goodbye\n", "Removing command group \"RBCIRC\"\n");
}

// This functions registers an ARX command.
// It can be used to read the localized command name
// from a string table stored in the resources.
void AddCommand(const char* cmdGroup, const char* cmdInt, const char* cmdLoc,
				const int cmdFlags, const AcRxFunctionPtr cmdProc, const int idLocal)
{
	char cmdLocRes[65];

	// If idLocal is not -1, it's treated as an ID for
	// a string stored in the resources.
	if (idLocal != -1) {

		// Load strings from the string table and register the command.
		::LoadString(_hdllInstance, idLocal, cmdLocRes, 64);
		acedRegCmds->addCommand(cmdGroup, cmdInt, cmdLocRes, cmdFlags, cmdProc);

	} else
		// idLocal is -1, so the 'hard coded'
		// localized function name is used.
		acedRegCmds->addCommand(cmdGroup, cmdInt, cmdLoc, cmdFlags, cmdProc);
}



// User defined function called from
// rbcirc() see Ch_3Commands.cpp
int printEntInfo(ads_name ent)
{
	struct resbuf *rbEnt;
	struct resbuf *rbTrav;
	
	rbEnt = acdbEntGet(ent);

	if(!rbEnt)
	{
		acutPrintf("\nFailed to get entities result buffer linked list. ");
		return 0;
	}

	rbTrav = rbEnt;

	while(rbTrav)
	{

		switch(rbTrav->restype)
		{
			case -1 :	// Ename
				acutPrintf("The entity name is <Entity name: %x> ",
							rbTrav->resval.rstring);
			break;

			case 0 :	// Entity type
				acutPrintf("\nThe entity is a %s on ", rbTrav->resval.rstring);
			break;

			case 8 :	// Layer
				acutPrintf("layer \"%s\". ", rbTrav->resval.rstring);
			break;

			case 10 :	// Center point
				acutPrintf("\nThe center point is (%.2lf, %.2lf, %.2lf). ",
							rbTrav->resval.rpoint[X],
							rbTrav->resval.rpoint[Y],
							rbTrav->resval.rpoint[Z]);
			break;

			case 40 :	// Radius
				acutPrintf("\nThe radius = %.5lf ", rbTrav->resval.rreal);
			break;

			case 210 :	// Plane orientation
				acutPrintf("\nThe planar orientation is (%.2lf, %.2lf, %.2lf). ",
							rbTrav->resval.rpoint[X],
							rbTrav->resval.rpoint[Y],
							rbTrav->resval.rpoint[Z]);

			break;

			default :
			break;
		} // switch

		rbTrav = rbTrav->rbnext;

	} // while
	
	if(rbEnt)
	{
		acutRelRb(rbEnt);
	}

	return 1;
}